package de.unikoblenz.west.csxpoi.server;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openrdf.query.BindingSet;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.http.HTTPRepository;

/**
 * HTTP URI dereferencing for vocabulary ontology resources.
 */
public class RdfVocabulary extends HttpServlet {
	
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		
		PrintWriter writer = ServletHelper.utf8Writer(response);
		RdfWriter.setN3ContentType(response);
		
		try {
			Repository repository = new HTTPRepository(Constants.SESAME_SERVER, Constants.REPOSITORY_ID);
			
			try {
				repository.initialize();
				RepositoryConnection connection = repository.getConnection();
			
				try {
					TupleQuery query = connection.prepareTupleQuery(QueryLanguage.SPARQL,
							"PREFIX base: <" + Constants.NS_BASE + "> " +
							"PREFIX rdfs: <" + Constants.NS_RDFS + "> " +
							"SELECT ?s ?p ?o WHERE {" +
							" ?s rdfs:subClassOf base:Poi ;" +
							"  rdfs:label ?name ." +
							" ?s ?p ?o ." +
							" FILTER (?s != ?o)" + // no self-subclasses
							" FILTER (?o != rdfs:Resource)" +
							" FILTER (?s != base:Poi)" +
							"} ORDER BY ASC(?name)");
					TupleQueryResult result = query.evaluate();
					try {
						while (result.hasNext()) {
							BindingSet bindingSet = result.next();
							RdfWriter.writeNTriple(writer,
									bindingSet.getValue("s"),
									bindingSet.getValue("p"),
									bindingSet.getValue("o"));
						}
					} finally {
						result.close();
					}
					
				} finally {
					connection.close();
				}
			} catch (RepositoryException e) {
				throw new ServerException();
			} catch (MalformedQueryException e) {
				throw new ServerException();
			} catch (QueryEvaluationException e) {
				throw new ServerException();
			}
		} catch (ServerException e) {
			e.printStackTrace();
		}
	}
	
}
